<template>
  <div class="screenshot-container">
    <div class="main-content">
      <div
        class="mask"
        :style="maskStyle"
        v-show="isScreenshotMode"
        ref="mask"
      ></div>
      <div
        class="screenshot-area"
        :style="screenshotAreaStyle"
        v-show="isScreenshotMode"
        @mousedown="startMove"
        ref="screenshotArea"
      >
        <div class="size-indicator">{{ areaSize }}</div>
        <div class="action-buttons" :class="{ top: isButtonsOnTop }">
          <button class="cancel-button" @click="cancelScreenshot">取消</button>
          <button class="save-button" @click="saveScreenshot">保存</button>
        </div>
        <div
          v-for="handle in resizeHandles"
          :key="handle.direction"
          class="resize-handle"
          :class="handle.direction"
          @mousedown.stop="startResize($event, handle.direction)"
        ></div>
      </div>
    </div>
  </div>
</template>

<script setup>
import html2canvas from 'html2canvas'

// 将 html2canvas 添加到全局对象
window.html2canvas = html2canvas
import { ref, computed, onMounted, onUnmounted, nextTick } from "vue";
const emits = defineEmits(["pushImgToNote"]);
// 常量定义
const MIN_SIZE = 50;
const INITIAL_SIZE = 200;

// 状态变量
const mask = ref(null);
const isScreenshotMode = ref(false);
const isMoving = ref(false);
const isResizing = ref(false);
const resizeDirection = ref("");
const moveStartX = ref(0);
const moveStartY = ref(0);
const resizeStartX = ref(0);
const resizeStartY = ref(0);
const screenshotArea = ref(null);
const screenshotAreaStyle = ref({
  left: "0px",
  top: "0px",
  width: `${INITIAL_SIZE}px`,
  height: `${INITIAL_SIZE}px`,
});

// 添加计算属性来获取当前窗口尺寸
const windowSize = ref({
  width: window.innerWidth,
  height: window.innerHeight,
});

// 计算属性
const areaSize = computed(() => {
  const width = parseInt(screenshotAreaStyle.value.width);
  const height = parseInt(screenshotAreaStyle.value.height);
  return `${width} x ${height}`;
});

const maskStyle = computed(() => {
  const rect = screenshotAreaStyle.value;
  return {
    "--clip-left": rect.left,
    "--clip-top": rect.top,
    "--clip-right": `calc(${rect.left} + ${rect.width})`,
    "--clip-bottom": `calc(${rect.top} + ${rect.height})`,
  };
});

// 调整大小手柄配置
const resizeHandles = [
  { direction: "nw" },
  { direction: "ne" },
  { direction: "sw" },
  { direction: "se" },
  { direction: "n" },
  { direction: "s" },
  { direction: "w" },
  { direction: "e" },
];

// 修改为响应式变量
const isButtonsOnTop = ref(false);

// 更新按钮位置的方法
const updateButtonPosition = () => {
  if (!screenshotArea.value) return;

  const rect = screenshotArea.value.getBoundingClientRect();
  const windowHeight = window.innerHeight;
  const buttonsHeight = 40; // 按钮区域的高度

  // 如果截图框底部到窗口底部的距离小于按钮高度，则显示在上方
  isButtonsOnTop.value = windowHeight - rect.bottom < buttonsHeight;
};

// 方法
const startScreenshot = () => {
  isScreenshotMode.value = true;
  const windowWidth = window.innerWidth;
  const windowHeight = window.innerHeight;

  screenshotAreaStyle.value = {
    left: `${(windowWidth - INITIAL_SIZE) / 2}px`,
    top: `${(windowHeight - INITIAL_SIZE) / 2}px`,
    width: `${INITIAL_SIZE}px`,
    height: `${INITIAL_SIZE}px`,
  };

  // 使用 nextTick 确保在 DOM 更新后更新按钮位置
  nextTick(updateButtonPosition);
};

const cancelScreenshot = () => {
  isScreenshotMode.value = false;
};

const startMove = (e) => {
  if (e.target.classList.contains("resize-handle")) return;
  isMoving.value = true;
  moveStartX.value = e.clientX - parseInt(screenshotAreaStyle.value.left);
  moveStartY.value = e.clientY - parseInt(screenshotAreaStyle.value.top);
};

const startResize = (e, direction) => {
  e.stopPropagation();
  isResizing.value = true;
  resizeDirection.value = direction;
  resizeStartX.value = e.clientX;
  resizeStartY.value = e.clientY;
};

const handleMouseMove = (e) => {
  if (!isScreenshotMode.value) return;

  if (isMoving.value) {
    const newLeft = e.clientX - moveStartX.value;
    const newTop = e.clientY - moveStartY.value;
    const width = parseInt(screenshotAreaStyle.value.width);
    const height = parseInt(screenshotAreaStyle.value.height);

    // 限制在可视区域内
    const maxLeft = window.innerWidth - width;
    const maxTop = window.innerHeight - height;

    screenshotAreaStyle.value.left = `${Math.max(
      0,
      Math.min(newLeft, maxLeft)
    )}px`;
    screenshotAreaStyle.value.top = `${Math.max(
      0,
      Math.min(newTop, maxTop)
    )}px`;

    // 使用 requestAnimationFrame 确保在渲染后更新按钮位置
    requestAnimationFrame(updateButtonPosition);
  } else if (isResizing.value) {
    const deltaX = e.clientX - resizeStartX.value;
    const deltaY = e.clientY - resizeStartY.value;
    const currentLeft = parseInt(screenshotAreaStyle.value.left);
    const currentTop = parseInt(screenshotAreaStyle.value.top);
    const currentWidth = parseInt(screenshotAreaStyle.value.width);
    const currentHeight = parseInt(screenshotAreaStyle.value.height);

    let newLeft = currentLeft;
    let newTop = currentTop;
    let newWidth = currentWidth;
    let newHeight = currentHeight;

    // 根据方向计算新的尺寸和位置
    switch (resizeDirection.value) {
      case "nw":
        newLeft = currentLeft + deltaX;
        newTop = currentTop + deltaY;
        newWidth = currentWidth - deltaX;
        newHeight = currentHeight - deltaY;
        break;
      case "ne":
        newTop = currentTop + deltaY;
        newWidth = currentWidth + deltaX;
        newHeight = currentHeight - deltaY;
        break;
      case "sw":
        newLeft = currentLeft + deltaX;
        newWidth = currentWidth - deltaX;
        newHeight = currentHeight + deltaY;
        break;
      case "se":
        newWidth = currentWidth + deltaX;
        newHeight = currentHeight + deltaY;
        break;
      case "n":
        newTop = currentTop + deltaY;
        newHeight = currentHeight - deltaY;
        break;
      case "s":
        newHeight = currentHeight + deltaY;
        break;
      case "w":
        newLeft = currentLeft + deltaX;
        newWidth = currentWidth - deltaX;
        break;
      case "e":
        newWidth = currentWidth + deltaX;
        break;
    }

    // 限制最小尺寸和可视区域
    if (newWidth >= MIN_SIZE && newHeight >= MIN_SIZE) {
      const maxLeft = window.innerWidth - newWidth;
      const maxTop = window.innerHeight - newHeight;

      screenshotAreaStyle.value.left = `${Math.max(
        0,
        Math.min(newLeft, maxLeft)
      )}px`;
      screenshotAreaStyle.value.top = `${Math.max(
        0,
        Math.min(newTop, maxTop)
      )}px`;
      screenshotAreaStyle.value.width = `${newWidth}px`;
      screenshotAreaStyle.value.height = `${newHeight}px`;

      // 使用 requestAnimationFrame 确保在渲染后更新按钮位置
      requestAnimationFrame(updateButtonPosition);
    }

    resizeStartX.value = e.clientX;
    resizeStartY.value = e.clientY;
  }
};

const handleMouseUp = () => {
  isMoving.value = false;
  isResizing.value = false;
};

const handleResize = () => {
  windowSize.value = {
    width: window.innerWidth,
    height: window.innerHeight,
  };
};


//将图片转换为base64格式
function getBase64Image(img) {
  const canvas = document.createElement("canvas");
  canvas.width = img.width;
  canvas.height = img.height;
  const ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0, img.width, img.height);
  const dataURL = canvas.toDataURL("image/png"); // 可选其他值 image/jpeg
  return dataURL;
}

// 保存
const saveScreenshot = async () => {
  const rect = screenshotArea.value.getBoundingClientRect();
  const saveButton = document.querySelector(".save-button");
  const cancelButton = document.querySelector(".cancel-button");

  try {
    const canvas = await html2canvas(document.body, {
      ignoreElements: (element) =>
        element === screenshotArea.value ||
        element === mask.value ||
        element === saveButton ||
        element === cancelButton,
      scrollX: window.scrollX,
      scrollY: window.scrollY,
      scale: window.devicePixelRatio,
      useCORS: true,
      allowTaint: true,
      logging: true,
      backgroundColor: "#ffffff",
      windowWidth: document.documentElement.scrollWidth,
      windowHeight: document.documentElement.scrollHeight,
      foreignObjectRendering: true,
      onclone: (doc) => {
        // 处理图片/svg跨域导致不显示的问题
        let imgList = doc.querySelectorAll("img")
        let svgList = doc.querySelectorAll("svg")
        let list = [...imgList, ...svgList]
        list.forEach((item) => {
          if(item.src){
            item.crossOrigin = "*"; // 必须在image之前赋值
            item.src = getBase64Image(item);
          }
        });
      },
    });

    const croppedCanvas = document.createElement("canvas");
    const scale = window.devicePixelRatio;
    croppedCanvas.width = rect.width * scale;
    croppedCanvas.height = rect.height * scale;
    const ctx = croppedCanvas.getContext("2d");

    // 设置背景为白色
    ctx.fillStyle = "#ffffff";
    ctx.fillRect(0, 0, croppedCanvas.width, croppedCanvas.height);

    ctx.drawImage(
      canvas,
      (rect.left + window.scrollX) * scale,
      (rect.top + window.scrollY) * scale,
      rect.width * scale,
      rect.height * scale,
      0,
      0,
      croppedCanvas.width,
      croppedCanvas.height
    );
    const imgBase64 = croppedCanvas.toDataURL("image/png");
    const item = {
      img: imgBase64,
      noteContent: "",
    };
    emits("pushImgToNote", item);
    // const link = document.createElement("a");

    // link.href = croppedCanvas.toDataURL("image/png");
    // link.download = `screenshot_${Date.now()}.png`;
    // document.body.appendChild(link);
    // link.click();
    // document.body.removeChild(link);
  } catch (error) {
    console.error("截图保存失败:", error);
  } finally {
    isScreenshotMode.value = false;
  }
};

// 在组件挂载时添加滚动事件监听
onMounted(() => {
  window.addEventListener("mousemove", handleMouseMove);
  window.addEventListener("mouseup", handleMouseUp);
  window.addEventListener("resize", handleResize);
  window.addEventListener("scroll", updateButtonPosition);
});

onUnmounted(() => {
  window.removeEventListener("mousemove", handleMouseMove);
  window.removeEventListener("mouseup", handleMouseUp);
  window.removeEventListener("resize", handleResize);
  window.removeEventListener("scroll", updateButtonPosition);
});

defineExpose({
  startScreenshot,
});
</script>

<style scoped>
.screenshot-container {
  display: flex;
  padding: 20px;
  font-family: Arial, sans-serif;
}

.main-content {
  flex: 1;
  padding-right: 20px;
}

.screenshot-area {
  position: fixed;
  border: 1px dashed #151618B8;
  background: transparent;
  cursor: move;
  z-index: 1001;
  pointer-events: auto;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
}

.size-indicator {
  position: absolute;
  top: -25px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
}

.resize-handle {
  width: 10px;
  height: 10px;
  background: #fff;
  border: 1px solid #000;
  position: absolute;
  z-index: 1002;
  pointer-events: auto;
  box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
}

.resize-handle.nw {
  top: -5px;
  left: -5px;
  cursor: nw-resize;
  width: 4px;
  height: 4px
}
.resize-handle.ne {
  top: -5px;
  right: -5px;
  cursor: ne-resize;
  width: 4px;
  height: 4px
}
.resize-handle.sw {
  bottom: -5px;
  left: -5px;
  cursor: sw-resize;
  width: 4px;
  height: 4px
}
.resize-handle.se {
  bottom: -5px;
  right: -5px;
  cursor: se-resize;
  width: 4px;
  height: 4px
}
.resize-handle.n {
  top: -5px;
  left: 50%;
  transform: translateX(-50%);
  cursor: n-resize;
  width: 4px;
  height: 4px
}
.resize-handle.s {
  bottom: -5px;
  left: 50%;
  transform: translateX(-50%);
  cursor: s-resize;
  width: 4px;
  height: 4px
}
.resize-handle.w {
  left: -5px;
  top: 50%;
  transform: translateY(-50%);
  cursor: w-resize;
  width: 4px;
  height: 4px
}
.resize-handle.e {
  right: -5px;
  top: 50%;
  transform: translateY(-50%);
  cursor: e-resize;
  width: 4px;
  height: 4px
}

.action-buttons {
  position: absolute;
  display: flex;
  gap: 10px;
  right: 0;
  transition: all 0.2s ease;
}

.action-buttons.top {
  bottom: auto;
  top: -40px;
}

.action-buttons:not(.top) {
  bottom: -40px;
  top: auto;
}

.save-button,
.cancel-button {
  padding: 6px 12px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  transition: all 0.3s ease;
}

.save-button {
  background: #0080D1;
  color: white;
  border: none;
}

.save-button:hover {
  background: #0080D1;
}

.cancel-button {
  background: #fff;
  color: #0080D1;
  border: none;
}

.cancel-button:hover {
  background: #fff;
}

.mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  z-index: 1000;
  clip-path: polygon(
    0% 0%,
    0% 100%,
    100% 100%,
    100% 0%,
    0% 0%,
    var(--clip-left) var(--clip-top),
    var(--clip-right) var(--clip-top),
    var(--clip-right) var(--clip-bottom),
    var(--clip-left) var(--clip-bottom),
    var(--clip-left) var(--clip-top)
  );
}
</style>
